#!/usr/bin/env python
import logging
import os
import re
import subprocess
import sys

import ubiqis.parse_nm as up

if "UBIQIS_CACHE_DIR" in os.environ:
    cache_dir = os.environ["UBIQIS_CACHE_DIR"]
else:
    import uroot.config
    cache_dir = uroot.config.CACHE_DIR

def make():
    """Runs the shell commands needed to create a ubiqis shared library"""

    if not os.path.exists('./src/'):
        logging.debug('ubimake: exiting... not a c++ package')
        return

    urllib = 'x'
    compile_list = ['g++', '-c', '-I', 'inc', '-I', cache_dir, '-I', 
                    os.environ['UBIQIS_ROOT'], '-fPIC', '-shared']
    obj_list = []
    pkg_name = '?'
    logging.debug("ubimake: set initial variables")

    # Switched from dircache.listdir to os.listdir due to problems on linux
    for src in os.listdir('./src/'):
        if src.endswith('.cpp'):
            obj = re.sub(r'^(\w+)\.cpp$', r'\1.o', src)
            obj_list.append(obj)
            compile_list.append('./src/' + src)
    logging.debug("ubimake: updated compile and object list")

    # Compile list
    try:
        p = subprocess.Popen(up.build_command_line(compile_list), shell=True, 
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        retcode = p.wait()

        if retcode < 0:
            logging.error("Child was terminated by signal %d" % -retcode)
        else:
            logging.debug("Child returned %d" % retcode)
            for line in p.stdout:
                logging.debug(line)
            logging.debug("ubimake: called compile list")
            if retcode > 0:
                for line in p.stderr:
                    logging.error(line)
    except OSError, e:
        logging.error("Execution failed:" +  repr(e))

    curr = up.getubi(os.getcwd())
    libs = up.get_ubiq_libs_from_nm(obj_list)
    for lib in libs:
        if curr == up.getubi(lib):
            urllib = lib

    baselib = os.path.basename(urllib)

    if up.get_platform() == 'Darwin':
        link_list = ['g++', '-dynamiclib', '-o', baselib]
    else:
        link_list = ['g++', '-shared', '-Wl,-soname,' + baselib, '-o', baselib]
    for obj in obj_list:
        link_list.append(obj)
    for lib in libs:
        if lib != urllib:
            link_list.append(lib)

    logging.debug("ubimake: set link list")

    # Call link list
    try:
        p = subprocess.Popen(up.build_command_line(link_list), shell=True,
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        retcode = p.wait()
        if retcode < 0:
            logging.error("Child was terminated by signal %d" % -retcode)
        else:
            logging.debug("Child returned %d" % retcode)
            for line in p.stdout:
                logging.debug(line)
            logging.debug("ubimake: called link list")
            if retcode > 0:
                for line in p.stderr:
                    logging.error(line)
    except OSError, e:
        logging.error("Execution failed:" + repr(e))

    # Move lib to cache root
    try:
        p = subprocess.Popen(up.build_command_line(['mv', baselib, cache_dir]), 
                             shell=True, stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        retcode = p.wait()
        if retcode < 0:
            logging.error("Child was terminated by signal %d" % -retcode)
        else:
            logging.debug("Child returned: %d" % retcode)
            for line in p.stdout:
                logging.debug(line)
            logging.debug("ubimake: called move")
            if retcode > 0:
                for line in p.stderr:
                    logging.error(line)
    except OSError, e:
        logging.error("Execution failed: " + repr(e))

if __name__ == "__main__":
    make()
